package com.filetransfer.api;
import com.filetransfer.api.generated.ShareItemControllerApi;
import com.filetransfer.api.generated.invoker.ApiException;
import com.filetransfer.api.generated.models.ModelFile;
import com.filetransfer.api.generated.models.NewShareItemInfo;
import com.filetransfer.api.generated.models.ShareItem;
import com.filetransfer.api.upload.FileUpload;
import cn.hutool.core.lang.func.Func0;
import lombok.Getter;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
 * @noinspection VariableTypeCanBeExplicit
 */
public class ShareCollection {
    private final FileUpload fileUpload;
    private final ShareItemControllerApi shareItemApi;
    public ShareCollection(int chunkSize) {
        fileUpload = new FileUpload(chunkSize);
        var client = ApiHelper.newApiClient();
        shareItemApi = new ShareItemControllerApi(client);
    }
    @Getter
    private final List<String> files = new ArrayList<>();
    public void addFile(String fileName, Func0<InputStream> getFile, @Nullable FileUpload.ChunkProgressListener onProgress) {
        var fileMd5 = fileUpload.uploadFile(fileName, getFile, progressInfo -> {
            System.out.println("上传进度：" + progressInfo);
            if (onProgress != null) {
                onProgress.onProgress(progressInfo);
            }
        });
        files.add(fileMd5);
    }
    public void addFile(File file, @Nullable FileUpload.ChunkProgressListener onProgress) {
        var fileMd5 = fileUpload.uploadFile(file, progressInfo -> {
            System.out.println("上传进度：" + progressInfo);
            if (onProgress != null) {
                onProgress.onProgress(progressInfo);
            }
        });
        files.add(fileMd5);
    }
    public record ShareResult(ShareItem share, List<java.net.URL> links) {}
    public record ShareResultToken(ShareItem share, String editToken, List<java.net.URL> links) {}
    /**
     * 创建分享
     */
    public ShareResultToken makeShare() {
        if (files.size() == 0) {
            throw new RuntimeException("请先上传文件");
        }
        // 创建分享
        var fileArray = files.stream().distinct().collect(Collectors.toList());
        files.clear();
        // 创建分享
        try {
            var share = shareItemApi.createShareItem(new NewShareItemInfo().files(fileArray));
            var info = shareItemApi.getShareItemById(share.getShareItem().getCode());
            var links = info.getFiles().stream().map(file -> {
                try {
                    return shareItemApi.getShareItemFilesCall(share.getShareItem().getCode(), file.getMd5(), file.getFileName(), null).request().url().url();
                } catch (ApiException e) {
                    throw new RuntimeException(e);
                }
            }).collect(Collectors.toList());
            return new ShareResultToken(share.getShareItem(), share.getEditToken(), links);
        } catch (ApiException e) {
            throw new RuntimeException(e);
        }
    }
    //    public List<java.net.URL> getFilesByShareCode(String ShareCode) throws ApiException {
//        var info = shareItemApi.getShareItemById(ShareCode);
//        var links = info.getFiles().stream()
//                .map(file -> {
//                    try {
//                        return shareItemApi.getShareItemFilesCall(
//                                ShareCode, file.getMd5(), file.getFileName(), null
//                        ).request().url().url();
//                    } catch (ApiException e) {
//                        throw new RuntimeException(e);
//                    }
//                })
//                .collect(Collectors.toList());
//        System.out.println(links);
//        return links;
//    }
    public static ShareResult getInfoByShareCode(String ShareCode) {
        ShareCollection collection = new ShareCollection(1024);
        return collection.getByShareCode(ShareCode);
    }
    public ShareResult getByShareCode(String ShareCode) {
        ShareItem info;
        try {
            info = shareItemApi.getShareItemById(ShareCode);
        } catch (ApiException e) {
            throw new RuntimeException(e);
        }
        var links = info.getFiles().stream().map(file -> {
            try {
                return shareItemApi.getShareItemFilesCall(ShareCode, file.getMd5(), file.getFileName(), null).request().url().url();
            } catch (ApiException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());
        return new ShareResult(info, links);
    }
    public static URL getDownloadLink(String code, ModelFile file) {
        try {
            return new ShareItemControllerApi(ApiHelper.newApiClient()).getShareItemFilesCall(code, file.getMd5(), file.getFileName(), null).request().url().url();
        } catch (ApiException e) {
            throw new RuntimeException(e);
        }
    }
}
